package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.help.menu.InitJxcMenuHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.AccordConfigMenuPojo;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.enums.AccessLinkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ProductErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.AccordConfigMenuEnum;
import com.xbongbong.pro.enums.menu.enums.JXCMenuEnum;
import com.xbongbong.pro.product.pojo.dto.ProductSerialDTO;
import com.xbongbong.pro.product.pojo.dto.ProductSerialFieldDTO;
import com.xbongbong.pro.product.pojo.dto.ProductSerialFlowDTO;
import com.xbongbong.pro.product.pojo.vo.ProductSerialFlowVO;
import com.xbongbong.pro.product.pojo.vo.ProductSerialVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.InstockProductEntity;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.ProductSerialBalanceEntity;
import com.xbongbong.saas.domain.entity.ProductSerialFlowEntity;
import com.xbongbong.saas.domain.entity.ext.InstockEntityExt;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.domain.entity.ext.WarehouseEntityExt;
import com.xbongbong.saas.enums.InstockTypeEnum;
import com.xbongbong.saas.enums.LinkProductSelectSerialEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.AssembleEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.ProductSerialBalanceEnum;
import com.xbongbong.saas.enums.business.SerialEnum;
import com.xbongbong.saas.enums.business.SerialStatusEnum;
import com.xbongbong.saas.enums.business.StockFlowBillEnum;
import com.xbongbong.saas.enums.business.WarehouseEnum;
import com.xbongbong.saas.help.workflow.ProductSerialHelp;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.InstockModel;
import com.xbongbong.saas.model.InstockProductModel;
import com.xbongbong.saas.model.OutstockProductModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.ProductSerialBalanceModel;
import com.xbongbong.saas.model.ProductSerialFlowModel;
import com.xbongbong.saas.model.RefundModel;
import com.xbongbong.saas.model.ReturnedPurchaseProductModel;
import com.xbongbong.saas.model.TransferProductModel;
import com.xbongbong.saas.model.WarehouseModel;
import com.xbongbong.saas.model.WarehouseOristockProductModel;
import com.xbongbong.saas.service.ProductSerialService;
import com.xbongbong.saas.service.toolbox.help.ProductHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
 * 序列号
 *
 * @author jiantao.xiong
 * @date 2020/5/21
 */
@Service("productSerialSerice")
public class ProductSerialServiceImpl implements ProductSerialService {

    private static final Logger LOG = LoggerFactory.getLogger(ProductSerialServiceImpl.class);

    @Resource
    private ProductSerialBalanceModel productSerialBalanceModel;
    @Resource
    private ProductSerialFlowModel productSerialFlowModel;
    @Resource
    private InstockModel instockModel;
    @Resource
    private InstockProductModel instockProductModel;
    @Resource
    private OutstockProductModel outstockProductModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private InitJxcMenuHelp initJxcMenuHelp;
    @Resource
    private WarehouseModel warehouseModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private WarehouseOristockProductModel warehouseOristockProductModel;
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private ReturnedPurchaseProductModel returnedPurchaseProductModel;
    @Resource
    private TransferProductModel transferProductModel;
    @Resource
    private RefundModel refundModel;
    @Resource
    private ProductHelp productHelp;
    @Resource
    private ProductSerialHelp productSerialHelp;
    @Resource
    private FormDataHelp formDataHelp;

    //需要录入序列号单据
    private static final List<Integer> entrySeqForm = Arrays.asList(XbbRefTypeEnum.PURCHASE_INSTOCK.getCode(), XbbRefTypeEnum.ORI_STOCK.getCode(), XbbRefTypeEnum.PRODUCTION_INSTOCK.getCode());
    // 需要选择序列号单据
    private static final List<Integer> selectSeqForm = Arrays.asList(XbbRefTypeEnum.RETURNED_MATERIEL_INSTOCK.getCode(), XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode(), XbbRefTypeEnum.REFUND_INSTOCK.getCode(), XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(), XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode(), XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode(), XbbRefTypeEnum.TRANSFER.getCode());

    @Override
    public void saveSerial(SaasFormSaveDTO saasFormSaveDTO, String productStr) throws XbbException {
        productSerialHelp.saveSerial(saasFormSaveDTO.getCorpid(), saasFormSaveDTO.getBusinessType(), saasFormSaveDTO.getNewData(), saasFormSaveDTO.getNewPaasFormDataEntity().getId(), saasFormSaveDTO.getNewPaasFormDataEntity().getSerialNo(), productStr);
    }

    @Override
    public void deleteSerial(String corpid, List<Long> refIdIn, Integer businessType) throws XbbException {
        productSerialBalanceModel.deleteSerial(corpid, refIdIn, businessType);
    }

    /**
     * 删除单据前置校验：已发生其他业务的序列号单据不允许删除
     *
     * @param refIdIn      删除的单据id
     * @param corpid       公司id
     * @param businessType 删除单据的业务类型
     */
    @Override
    public void preCheckDelSerial(List<Long> refIdIn, String corpid, Integer businessType) throws XbbException {
        // 序列号入库单删除校验：如果该序列号已存在其他业务中，则不允许删除
        Map<String, ProductSerialBalanceEntity> productSerialBalanceMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<String> seqKeyList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> productIdList = new ArrayList<>(PaasConstant.ADDRESS_KEN_LENGTH);
        List<ProductSerialFlowEntity> flowEntityList = productSerialFlowModel.getFlowByRefIdAndBusiness(refIdIn, businessType, corpid);
        flowEntityList.forEach(item -> productIdList.add(item.getProductId()));
        // 序列号产品
        List<ProductEntityExt> productEntityExts = productModel.getProductListByIdIn(corpid, productIdList, DelEnum.NORMAL.getDel());
        List<Long> closeSerial = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ProductEntityExt productEntityExt : productEntityExts) {
            JSONObject data = productEntityExt.getData();
            int enableSerialNumber = data.getIntValue(ProductEnum.ENABLE_SERIAL_NUMBER.getAttr());
            if (BasicConstant.ZERO.equals(enableSerialNumber)) {
                // 删除的单据中关闭序列号管理的产品id
                closeSerial.add(productEntityExt.getId());
            }
        }
        if (CollectionUtils.isNotEmpty(flowEntityList)) {
            flowEntityList.forEach(item -> seqKeyList.add(item.getSeqKey()));
            // 查询删除单据对应序列号流水记录
            List<ProductSerialBalanceEntity> productSerialBalanceEntityList = productSerialBalanceModel.getBySeqKeyList(seqKeyList, corpid);
            productSerialBalanceEntityList.forEach(item -> productSerialBalanceMap.put(item.getSeqKey(), item));

            Set<String> sheetNoList = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (ProductSerialFlowEntity productSerialFlowEntity : flowEntityList) {
                // 已关闭序列号管理的产品不做删除校验
                if (closeSerial.contains(productSerialFlowEntity.getProductId())) {
                    continue;
                }
                // productId + seq 产品序列号唯一标识
                String seqKey = productSerialFlowEntity.getSeqKey();
                // 序列号关联单据的id，即当前删除的单据id
                Long refId = productSerialFlowEntity.getRefId();

                // 获取唯一序列号标识的结存数据
                ProductSerialBalanceEntity serialBalanceEntity = productSerialBalanceMap.get(seqKey);
                // 判断当前序列号结存数据与删除单据的序列号流水数据，校验业务类型以及关联单据id是否一致
                if (Objects.nonNull(serialBalanceEntity) && !(Objects.equals(businessType, serialBalanceEntity.getBusinessType()) && Objects.equals(refId, serialBalanceEntity.getRefId()))) {
                    sheetNoList.add(productSerialFlowEntity.getRefSheetNo());
                }
                // 因为结存表最后存在了入库单上所以上面逻辑走不到  在这里特殊处理
                // 调拨业务的入库单 也不允许删除
                if (Objects.equals(businessType,XbbRefTypeEnum.OTHER_INSTOCK.getCode()) && Objects.nonNull(refId)){
                    InstockEntityExt instockEntityExt = instockModel.getByKey(refId, corpid);
                    JSONObject data = instockEntityExt.getData();
                    if (Objects.nonNull(data)) {
                        Integer instockType = FastJsonHelper.getIntegerOrDefaultFromFormData(data, InstockEnum.TYPE.getAttr(), InstockTypeEnum.OTHER_INSTOCK.getCode());
                        if(Objects.equals(instockType, InstockTypeEnum.TRANSFER_INSTOCK.getCode())){
                            sheetNoList.add(productSerialFlowEntity.getRefSheetNo());
                        }
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(sheetNoList)) {
                throw new XbbException(ProductErrorCodeEnum.API_ERROR_205081, XbbRefTypeEnum.getByCode(businessType).getName() + String.format(ProductErrorCodeEnum.API_ERROR_205081.getMsg(), sheetNoList.toString()));
            }
        }
    }

    /**
     * 序列号保存前置校验，避免重复序列号，主要是避免审批导致的序列号重复
     *
     * @param formData     表单数据
     * @param productArray 关联产品数据
     * @param productAttr  关联产品attr
     * @param businessType 业务类型
     * @param corpid       公司id
     * @throws XbbException 校验不通过
     */
    @Override
    public void preCheckSaveSerial(JSONObject formData, JSONArray productArray, String productAttr, Integer businessType, String corpid) throws XbbException {
        productHelp.preCheckSaveSerial(formData, productArray, productAttr, businessType, corpid);
    }

    @Override
    public void dataConsistencyUpdateSeqSearch(String corpid, Long dataId, Integer visible) {
        try {
            productSerialBalanceModel.updateBatchByParentId(corpid, dataId, visible);
        } catch (Exception e) {
            LOG.error("ProductSerialServiceImpl.dataConsistencyUpdateSeqSearch fail， corpid=" + corpid + " dataId=" + dataId + "  visible=" + visible, e);
            e.printStackTrace();
        }
    }

    /**
     * 删除单据，序列号结存更新为最近时间的一条流水数据
     *
     * @param balanceEntities 删除单据的序列号结存记录
     * @param corpid          公司id
     * @throws XbbException 异常
     */
    private void updateLastSerialFlow(List<ProductSerialBalanceEntity> balanceEntities, String corpid) throws XbbException {
        for (ProductSerialBalanceEntity balanceEntity : balanceEntities) {
            String seqKey = balanceEntity.getSeqKey();
            // 序列号的最近一次流水记录
            ProductSerialFlowEntity lastSerialFlow = productSerialFlowModel.getLastSerialFlow(corpid, seqKey, balanceEntity.getRefId());
            if (Objects.nonNull(lastSerialFlow)) {
                ProductSerialBalanceEntity productSerialBalanceEntity = new ProductSerialBalanceEntity(lastSerialFlow);
                productSerialBalanceEntity.setId(balanceEntity.getId());
                productSerialBalanceModel.update(productSerialBalanceEntity);
            }
        }
    }

    @Override
    public ProductSerialVO getSerialFields(ProductSerialFieldDTO productSerialFieldDTO) throws XbbException {
        ProductSerialVO productSerialVO = new ProductSerialVO();
        List<FieldAttrEntity> explainList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        // 录入序列号弹窗表头
        FieldAttrEntity seqField = new FieldAttrEntity();
        seqField.setFieldType(FieldTypeEnum.SUB_FORM.getType());
        seqField.setAttr(ProductConstant.SEQ);
        seqField.setAttrName("序列号");
        seqField.setVisible(1);
        seqField.setEditable(1);
        seqField.setAttrType(FieldTypeEnum.SUB_FORM.getEsalias());
        seqField.setSubForm(new SubFormPoJo());

        List<FieldAttrEntity> subField = new ArrayList<>();
        FieldAttrEntity serialField = new FieldAttrEntity();
        BeanUtil.copyProperties(SerialEnum.SERIAL, serialField);
        serialField.setAttrType(FieldTypeEnum.TEXT.getAlias());
        serialField.setEditable(1);
        subField.add(serialField);

        FieldAttrEntity memoField = new FieldAttrEntity();
        memoField.setAttrType(FieldTypeEnum.TEXT.getAlias());
        BeanUtil.copyProperties(SerialEnum.MEMO, memoField);
        memoField.setEditable(1);
        subField.add(memoField);

        seqField.getSubForm().setItems(subField);
        explainList.add(seqField);

        productSerialVO.setExplainList(explainList);
        return productSerialVO;
    }

    /**
     * 编辑和详情页序列号回显
     *
     * @param productSerialDTO 产品序列号DTO
     * @return 产品序列号
     * @throws XbbException 异常
     */
    @Override
    public ProductSerialVO selectSerial(ProductSerialDTO productSerialDTO) throws XbbException {
        ProductSerialVO productSerialVO = getSerialFields(new ProductSerialFieldDTO());
        String corpid = productSerialDTO.getCorpid();
        Integer businessType = productSerialDTO.getBusinessType();
        Long refId = productSerialDTO.getRefId();
        Long productSubId = productSerialDTO.getProductSubId();

        Map<String, Object> serialParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        serialParam.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        serialParam.put("corpid", corpid);
        serialParam.put("page", productSerialDTO.getPage());

        if (Objects.equals(businessType, XbbRefTypeEnum.ASSEMBLE.getCode())) {
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery(ParameterConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
            IndexTypeEnum indexTypeEnum = null;
            int subBusinessType = 0;
            if (AssembleEnum.OUT_PRODUCTS.getAttr().equals(productSerialDTO.getAttr())) {
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_OTHER_OUTSTOCK;
                boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.REF_ID), productSerialDTO.getRefId()));
                boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.TYPE), OutstockTypeEnum.ASSEMBLE_OUTSTOCK.getCode()));
                subBusinessType = XbbRefTypeEnum.OTHER_OUTSTOCK.getCode();
            } else if (AssembleEnum.IN_PRODUCTS.getAttr().equals(productSerialDTO.getAttr())) {
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_OTHER_INSTOCK;
                boolQueryBuilder.filter(termQuery(InstockEnum.getEsAttr4Keyword(InstockEnum.REF_ID), productSerialDTO.getRefId()));
                boolQueryBuilder.filter(termQuery(InstockEnum.getEsAttr4Keyword(InstockEnum.TYPE), InstockTypeEnum.ASSEMBLE_INSTOCK.getCode()));
                subBusinessType = XbbRefTypeEnum.OTHER_INSTOCK.getCode();
            }
            // 设置join_field
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
            searchSourceBuilder.query(boolQueryBuilder);
            List<PaasFormDataEntityExt> paasFormDataEntityExts = paasEsModel.list(searchSourceBuilder, indexTypeEnum, null, 1, 1);
            // 装配单的下游出入库单
            if (CollectionUtils.isNotEmpty(paasFormDataEntityExts)) {
                PaasFormDataEntityExt paasFormDataEntityExt = paasFormDataEntityExts.get(0);
                if (Objects.equals(subBusinessType, XbbRefTypeEnum.OTHER_INSTOCK.getCode())) {
                    InstockProductEntity instockProductEntity = instockProductModel.getProductsByInstockIdAndRefProductId(paasFormDataEntityExt.getId(), productSubId, corpid);
                    if (Objects.nonNull(instockProductEntity)) {
                        serialParam.put("refProductId", instockProductEntity.getId());
                    }
                } else if (Objects.equals(subBusinessType, XbbRefTypeEnum.OTHER_OUTSTOCK.getCode())) {
                    OutstockProductEntity outstockProductEntity = outstockProductModel.getProductsByInstockIdAndRefProductId(paasFormDataEntityExt.getId(), productSubId, corpid);
                    if (Objects.nonNull(outstockProductEntity)) {
                        serialParam.put("refProductId", outstockProductEntity.getId());
                    }
                }
                serialParam.put("refId", paasFormDataEntityExt.getId());
                serialParam.put("businessType", subBusinessType);
            }
        } else if (!productSerialDTO.getBusinessType().equals(XbbRefTypeEnum.ORI_STOCK.getCode())) {
            serialParam.put("businessType", businessType);
            serialParam.put("refId", refId);
            serialParam.put("refProductId", productSubId);
        } else {
            Long warehouseId = productSerialDTO.getWarehouseId();
            serialParam.put("businessType", businessType);
            serialParam.put("warehouseId", warehouseId);
            serialParam.put("refProductId", productSubId);
        }
        PageHelper pageHelper = PageHelperUtil.getPageHelper(serialParam, productSerialFlowModel, productSerialDTO.getPageSize());
        List<ProductSerialFlowEntity> entitys = (List<ProductSerialFlowEntity>) PageHelperUtil.getEntityList(serialParam, pageHelper, productSerialFlowModel);
        JSONArray serialArray = new JSONArray();
        for (ProductSerialFlowEntity entity : entitys) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(SerialEnum.SERIAL.getAttr(), entity.getSeq());
            jsonObject.put(SerialEnum.MEMO.getAttr(), entity.getMemo());
            serialArray.add(jsonObject);
        }
        productSerialVO.setSeq(serialArray);
        productSerialVO.setPageHelper(pageHelper);
        return productSerialVO;
    }

    @Override
    public ProductSerialFlowVO getSerialFlow(ProductSerialFlowDTO productSerialFlowDTO) throws XbbException {
        ProductSerialFlowVO productSerialFlowVO = new ProductSerialFlowVO();
        String corpid = productSerialFlowDTO.getCorpid();
        Long dataId = productSerialFlowDTO.getDataId();
        // 解释
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.SEQ_SEARCH.getCode(), corpid);
        if (Objects.isNull(paasFormExplainEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        List<FieldAttrEntity> explainList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        // 序列号跟踪移除不展示的字段
        List<String> fieldAttrList = Arrays.asList(ProductSerialBalanceEnum.TIME.getAttr(), ProductSerialBalanceEnum.BUSINESS_TYPE.getAttr(), ProductSerialBalanceEnum.SHEET_NO.getAttr(), ProductSerialBalanceEnum.BUSINESS_ID.getAttr(), ProductSerialBalanceEnum.WAREHOUSE_ID.getAttr());
        explainList.removeIf(item -> !fieldAttrList.contains(item.getAttr()));
        // 序列号结存记录
        ProductSerialBalanceEntity productSerialBalanceEntity = productSerialBalanceModel.getByKey(dataId, corpid);
        String seqKey = productSerialBalanceEntity.getSeqKey();
        // 产品数据
        JSONObject serialFlowData = new JSONObject();
        ProductEntityExt productEntityExt = productModel.getByKey(productSerialBalanceEntity.getProductId(), corpid);
        JSONObject productEntityExtData = productEntityExt.getData();
        serialFlowData.put(ProductSerialBalanceEnum.NAME.getAttr(), productEntityExtData.getString(ProductEnum.NAME.getAttr()));
        String specification = "";
        if (Objects.equals("0", productEntityExtData.getString(ProductEnum.SPECIFICATION.getAttr()))) {
            // 单规格
            specification = productEntityExtData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr());
        } else if ("1".equals(productEntityExtData.getString(ProductEnum.SPECIFICATION.getAttr()))) {
            // 多规格
            JSONObject specificationData = productEntityExtData.getJSONObject(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr());
            if (specificationData != null) {
                Collection<Object> values = specificationData.values();
                specification = values.toString().replaceAll("[\\[\\]]", "");
            }
        }
        if (StringUtils.isEmpty(specification)) {
            specification = BasicConstant.NULL_SHOW_STR;
        }
        serialFlowData.put(ProductSerialBalanceEnum.SPECIFICATION.getAttr(), specification);
        serialFlowData.put(ProductSerialBalanceEnum.SEQ.getAttr(), productSerialBalanceEntity.getSeq());
        serialFlowData.put(ProductSerialBalanceEnum.STATUS.getAttr(), Objects.requireNonNull(SerialStatusEnum.getByCode(productSerialBalanceEntity.getStatus())).getName());
        // 仓库数据
        JSONArray serialFlowArray = new JSONArray();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<Long> warehouseIdSet = new HashSet<>();
        List<ProductSerialFlowEntity> productSerialFlowEntityList = productSerialFlowModel.getBySeqKey(seqKey, corpid);
        productSerialFlowEntityList.forEach(item -> warehouseIdSet.add(item.getWarehouseId()));
        params.put(ParameterConstant.CORPID, corpid);
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        params.put("idIn", warehouseIdSet);
        List<WarehouseEntityExt> warehouseEntityList = warehouseModel.findEntitys(params);
        Map<Long, WarehouseEntityExt> warehouseMap = new HashMap<>(warehouseEntityList.size());
        warehouseEntityList.forEach(item -> warehouseMap.put(item.getId(), item));

        if (Objects.equals(productSerialFlowDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
            serialFlowData.put(ProductSerialBalanceEnum.SERIALNO.getAttr(), productEntityExtData.getString(ProductEnum.PRODUCT_NO.getAttr()));
            if (Objects.isNull(productSerialBalanceEntity.getMemo())) {
                serialFlowData.put(ProductSerialBalanceEnum.MEMO.getAttr(), "");
            } else {
                serialFlowData.put(ProductSerialBalanceEnum.MEMO.getAttr(), productSerialBalanceEntity.getMemo());
            }
            // APP端序列号结存仓库
            WarehouseEntityExt warehouse = warehouseMap.get(productSerialBalanceEntity.getWarehouseId());
            JSONObject warehouseObj = warehouse.getData();
            serialFlowData.put(ProductSerialBalanceEnum.WAREHOUSE_ID.getAttr(), warehouseObj.getString(WarehouseEnum.WAREHOUSE_NAME.getAttr()));
            if (Objects.equals(productSerialBalanceEntity.getStatus(), SerialStatusEnum.OUT_STOCK.getCode())) {
                serialFlowData.put(ProductSerialBalanceEnum.WAREHOUSE_ID.getAttr(), "--");
            }
        }

        Map<Integer, List<Long>> dataInMap = new HashMap<>(productSerialFlowEntityList.size());
        productSerialFlowEntityList.forEach(item->{
            Integer businessType;
            Long id ;
            if (Objects.equals(XbbRefTypeEnum.ORI_STOCK.getCode(), item.getBusinessType())) {
                businessType = XbbRefTypeEnum.WAREHOUSE.getCode();
                id = item.getWarehouseId();
            } else {
                id = item.getRefId();
                businessType = item.getBusinessType();
            }
            if (dataInMap.containsKey(businessType)) {
                List<Long> idIn = dataInMap.get(businessType);
                idIn.add(id);
                dataInMap.put(businessType, idIn);
            } else {
                List<Long> idIn = new ArrayList<>();
                idIn.add(id);
                dataInMap.put(businessType, idIn);
            }
        });
        List<PaasFormDataEntityExt> formDataList = null;
        Map<Integer, Map<Long, PaasFormDataEntityExt>> businessTypeFormDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (Map.Entry<Integer, List<Long>> entry : dataInMap.entrySet()) {
            Integer key = entry.getKey();
            List<Long> item = entry.getValue();
            formDataList = formDataHelp.getByDataIdList(item, key, SaasMarkEnum.SAAS.getCode(), null, corpid);
            Map<Long, PaasFormDataEntityExt> formDataMap = new HashMap<>(formDataList.size());
            formDataList.forEach(formDataEntityExt->{
                formDataMap.put(formDataEntityExt.getId(), formDataEntityExt);
            });
            businessTypeFormDataMap.put(key, formDataMap);
        }

        for (ProductSerialFlowEntity serialFlowEntity : productSerialFlowEntityList) {
            Long warehouseId = serialFlowEntity.getWarehouseId();
            JSONObject data = new JSONObject();
            data.put(ProductSerialBalanceEnum.BUSINESS_TYPE.getAttr(), XbbRefTypeEnum.getByCode(serialFlowEntity.getBusinessType()).getName());
            data.put(ProductSerialBalanceEnum.BUSINESS_ID.getAttr(), serialFlowEntity.getBusinessName());
            if (!Objects.equals(productSerialFlowDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
                data.put(ProductSerialBalanceEnum.SEQ.getAttr(), serialFlowEntity.getSeq());
            }
            // 仓库信息封装
            if (warehouseMap.containsKey(warehouseId)) {
                WarehouseEntityExt warehouse = warehouseMap.get(warehouseId);
                JSONObject warehouseObj = warehouse.getData();
                data.put(ProductSerialBalanceEnum.WAREHOUSE_ID.getAttr(), warehouseObj.getString(WarehouseEnum.WAREHOUSE_NAME.getAttr()));
            }
            // 其他基础信息封装
            if (Objects.equals(productSerialFlowDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
                data.put(StockFlowBillEnum.SHEET_NO.getAttr(), serialFlowEntity.getRefSheetNo());
                data.put(StockFlowBillEnum.TIME.getAttr(), DateTimeUtil.getStringEpochSecond(serialFlowEntity.getDate(), DateTimeUtil.SDFYMDHM));
            } else {
                JSONArray sheetArray = new JSONArray();
                JSONObject sheetObject = new JSONObject();
                sheetObject.put("name", serialFlowEntity.getRefSheetNo());
                sheetObject.put("saasMark", SaasMarkEnum.SAAS.getCode());
                if (Objects.equals(XbbRefTypeEnum.ORI_STOCK.getCode(), serialFlowEntity.getBusinessType())) {
                    Map<Long, PaasFormDataEntityExt> formDataMap = businessTypeFormDataMap.get(XbbRefTypeEnum.WAREHOUSE.getCode());
                    if (formDataMap.containsKey(serialFlowEntity.getWarehouseId()) && !FlowStatusEnum.getStatisticType().contains(formDataMap.get(serialFlowEntity.getWarehouseId()).getFlowStatus())) {
                        continue;
                    }
                    sheetObject.put("businessType", XbbRefTypeEnum.WAREHOUSE.getCode());
                    sheetObject.put("id", serialFlowEntity.getWarehouseId());
                } else {
                    Map<Long, PaasFormDataEntityExt> formDataMap = businessTypeFormDataMap.get(serialFlowEntity.getBusinessType());
                    if (formDataMap.containsKey(serialFlowEntity.getRefId()) && !FlowStatusEnum.getStatisticType().contains(formDataMap.get(serialFlowEntity.getRefId()).getFlowStatus())) {
                        continue;
                    }
                    sheetObject.put("id", serialFlowEntity.getRefId());
                    sheetObject.put("businessType", serialFlowEntity.getBusinessType());
                }
                sheetArray.add(sheetObject);
                data.put(StockFlowBillEnum.SHEET_NO.getAttr(), sheetArray);
                data.put(StockFlowBillEnum.TIME.getAttr(), serialFlowEntity.getDate());
            }
            serialFlowArray.add(data);
        }
        serialFlowData.put("serialFlowList", serialFlowArray);
        productSerialFlowVO.setSerialFlowData(serialFlowData);
        productSerialFlowVO.setExplainList(explainList);
        return productSerialFlowVO;
    }

    @Override
    public List<ProductSerialFlowEntity> getProductSerial(Long refId, Integer businessType, String corpid) throws XbbException {
        return productSerialFlowModel.getFlowByRefIdAndBusiness(Collections.singletonList(refId), businessType, corpid);
    }

    @Override
    public ProductSerialVO checkSerialStatus(ProductSerialDTO productSerialDTO) throws XbbException {
        if (CollectionUtils.isEmpty(productSerialDTO.getSerialNumber())) {
            throw new XbbException(ProductErrorCodeEnum.API_ERROR_205070);
        }
        String corpid = productSerialDTO.getCorpid();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("columns", "seq, memo");
        param.put("corpid", corpid);
        param.put("productId", productSerialDTO.getProductId());
        param.put("warehouseId", productSerialDTO.getWarehouseId());
        param.put("status", SerialStatusEnum.IN_STOCK.getCode());
        param.put("seqIn", productSerialDTO.getSerialNumber());
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        Integer businessType = productSerialDTO.getBusinessType();
        Integer type = productSerialDTO.getType();
        if (Objects.equals(businessType, XbbRefTypeEnum.OTHER_OUTSTOCK.getCode())) {
            if (Objects.equals(type, OutstockTypeEnum.TRANSFER_OUTSTOCK.getCode())) {
                param.put("businessType", XbbRefTypeEnum.TRANSFER.getCode());
                param.put("refProductId", productSerialDTO.getRefProductId());
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode())) {
            param.put("businessType", XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
            param.put("refProductId", productSerialDTO.getRefProductId());
        } else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE.getCode())) {
            param.put("businessType", XbbRefTypeEnum.PURCHASE_INSTOCK.getCode());
            param.put("refProductId", productSerialDTO.getRefProductId());
        } else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode())) {
            param.put("businessType", XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode());
            param.put("refProductId", productSerialDTO.getRefProductId());
            param.put("status", SerialStatusEnum.OUT_STOCK.getCode());
        } else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND_INSTOCK.getCode())) {
            param.put("businessType", XbbRefTypeEnum.REFUND.getCode());
            param.put("status", SerialStatusEnum.OUT_STOCK.getCode());
            param.put("refProductId", productSerialDTO.getRefProductId());
        } else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_MATERIEL_INSTOCK.getCode())) {
            param.put("businessType", XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode());
            param.put("status", SerialStatusEnum.OUT_STOCK.getCode());
            param.put("refProductId", productSerialDTO.getRefProductId());
        } else if (Objects.equals(businessType, XbbRefTypeEnum.OTHER_INSTOCK.getCode()) && Objects.equals(type, InstockTypeEnum.TRANSFER_INSTOCK.getCode())) {
            OutstockProductEntity outstockProductEntity = outstockProductModel.getByKey(productSerialDTO.getRefProductId(), corpid);
            param.put("refId", outstockProductEntity.getOutWarehouseId());
            param.put("businessType", XbbRefTypeEnum.OTHER_OUTSTOCK.getCode());
            param.put("status", SerialStatusEnum.OUT_STOCK.getCode());
            param.put("refProductId", productSerialDTO.getRefProductId());
            param.put("warehouseId", outstockProductEntity.getWarehouseId());
        }

        List<ProductSerialBalanceEntity> entitys = productSerialBalanceModel.findEntitys(param);
        if (entitys.isEmpty()) {
            //有上游单据的需要考虑序列号是否在上游单据
            if (param.containsKey("businessType")) {
                throw new XbbException(ProductErrorCodeEnum.API_ERROR_205090);
            }
            throw new XbbException(ProductErrorCodeEnum.API_ERROR_205078);
        }
        JSONArray serialArray = new JSONArray();
        for (ProductSerialBalanceEntity entity : entitys) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(SerialEnum.SERIAL.getAttr(), entity.getSeq());
            jsonObject.put(SerialEnum.MEMO.getAttr(), entity.getMemo());
            serialArray.add(jsonObject);
        }
        ProductSerialVO productSerialVO = new ProductSerialVO();
        productSerialVO.setSeq(serialArray);
        return productSerialVO;
    }

    @Override
    public void formatExportValue(List<PaasFormDataEntityExt> paasFormDataESList, FormDataListDTO formDataListDTO, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        List<PaasFormDataEntityExt> childFlowList = new ArrayList<>();
        List<String> seqKeyList = new ArrayList<>();
        paasFormDataESList.forEach(paasFormDataEntityExt -> seqKeyList.add(paasFormDataEntityExt.getRefProductId() + StringConstant.CROSS + Objects.toString(paasFormDataEntityExt.getData().get(ProductSerialBalanceEnum.SEQ.getAttr()), "")));
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, formDataListDTO.getCorpid());
        param.put("seqKeyIn", seqKeyList);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<ProductSerialFlowEntity> flowEntityList = productSerialFlowModel.findEntitys(param);
        Map<String, List<ProductSerialFlowEntity>> flowMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<Long> warehouseIdSet = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ProductSerialFlowEntity flowEntity : flowEntityList) {
            List<ProductSerialFlowEntity> productSerialFlowEntityList = flowMap.getOrDefault(flowEntity.getSeqKey(), new ArrayList<>());
            productSerialFlowEntityList.add(flowEntity);
            flowMap.put(flowEntity.getSeqKey(), productSerialFlowEntityList);
            warehouseIdSet.add(flowEntity.getWarehouseId());
        }
        param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, formDataListDTO.getCorpid());
        param.put(ParameterConstant.ID_IN, warehouseIdSet);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<WarehouseEntityExt> warehouseEntityExtList = warehouseModel.findEntitys(param);
        Map<Long, String> warehouseMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        warehouseEntityExtList.forEach(warehouseEntityExt -> warehouseMap.put(warehouseEntityExt.getId(), warehouseEntityExt.getData().getString(WarehouseEnum.WAREHOUSE_NAME.getAttr())));
        for (PaasFormDataEntityExt formDataEntityExt : paasFormDataESList) {
            List<ProductSerialFlowEntity> serialFlowEntityList = flowMap.getOrDefault(formDataEntityExt.getRefProductId() + StringConstant.CROSS + Objects.toString(formDataEntityExt.getData().get(ProductSerialBalanceEnum.SEQ.getAttr()), ""), new ArrayList<>());
            for (ProductSerialFlowEntity serialFlowEntity : serialFlowEntityList) {
                PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt();
                JSONObject data = new JSONObject();
                data.put(ProductSerialBalanceEnum.SERIALNO.getAttr(), formDataEntityExt.getData().getString(ProductSerialBalanceEnum.SERIALNO.getAttr()));
                data.put(ProductSerialBalanceEnum.NAME.getAttr(), formDataEntityExt.getData().getString(ProductSerialBalanceEnum.NAME.getAttr()));
                data.put(ProductSerialBalanceEnum.SPECIFICATION.getAttr(), formDataEntityExt.getData().getString(ProductSerialBalanceEnum.SPECIFICATION.getAttr()));
                data.put(ProductSerialBalanceEnum.SEQ.getAttr(), formDataEntityExt.getData().getString(ProductSerialBalanceEnum.SEQ.getAttr()));
                data.put(ProductSerialBalanceEnum.MEMO.getAttr(), serialFlowEntity.getMemo());
                data.put(ProductSerialBalanceEnum.BUSINESS_ID.getAttr(), serialFlowEntity.getBusinessName());
                if (Objects.equals(SerialStatusEnum.OUT_STOCK.getCode(), serialFlowEntity.getStatus())) {
                    data.put(ProductSerialBalanceEnum.WAREHOUSE_ID.getAttr(), "--");
                } else {
                    data.put(ProductSerialBalanceEnum.WAREHOUSE_ID.getAttr(), warehouseMap.getOrDefault(serialFlowEntity.getWarehouseId(), ""));
                }
                data.put(ProductSerialBalanceEnum.TIME.getAttr(), DateTimeUtil.getStringEpochSecond(serialFlowEntity.getDate(), DateTimeUtil.SDFDate));
                data.put(ProductSerialBalanceEnum.SHEET_NO.getAttr(), serialFlowEntity.getRefSheetNo());
                data.put(ProductSerialBalanceEnum.STATUS.getAttr(), Objects.isNull(SerialStatusEnum.getByCode(serialFlowEntity.getStatus())) ? "" : SerialStatusEnum.getByCode(serialFlowEntity.getStatus()).getName());
                data.put(ProductSerialBalanceEnum.BUSINESS_ID.getAttr(), serialFlowEntity.getBusinessName());
                data.put(ProductSerialBalanceEnum.BUSINESS_TYPE.getAttr(), XbbRefTypeEnum.getByCode(serialFlowEntity.getBusinessType()).getName());
                paasFormDataEntityExt.setData(data);
                childFlowList.add(paasFormDataEntityExt);
            }
        }
        paasFormDataESList.clear();
        paasFormDataESList.addAll(childFlowList);
    }

    @Override
    public ProductSerialVO getSerial(ProductSerialDTO productSerialDTO) throws XbbException {
        ProductSerialVO productSerialVO = getSerialFields(new ProductSerialFieldDTO());
        String corpid = productSerialDTO.getCorpid();
        Integer businessType = productSerialDTO.getBusinessType();
        Long productId = productSerialDTO.getProductId();
        Long warehouseId = productSerialDTO.getWarehouseId();
        Integer type = productSerialDTO.getType();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("columns", "seq, memo, business_type");
        param.put("corpid", corpid);
        param.put("productId", productId);
        param.put("warehouseId", warehouseId);
        param.put("page", productSerialDTO.getPage());
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        if (Objects.equals(businessType, XbbRefTypeEnum.OTHER_OUTSTOCK.getCode())) {
            if (Objects.equals(type, OutstockTypeEnum.TRANSFER_OUTSTOCK.getCode())) {
                param.put("businessType", XbbRefTypeEnum.TRANSFER.getCode());
                param.put("refProductId", productSerialDTO.getRefProductId());
            } else {
                param.put("status", SerialStatusEnum.IN_STOCK.getCode());
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.OTHER_INSTOCK.getCode())) {
            if (Objects.equals(type, InstockTypeEnum.TRANSFER_INSTOCK.getCode())) {
                OutstockProductEntity outstockProductEntity = outstockProductModel.getByKey(productSerialDTO.getRefProductId(), corpid);
                param.put("refId", outstockProductEntity.getOutWarehouseId());
                param.put("businessType", XbbRefTypeEnum.OTHER_OUTSTOCK.getCode());
                param.put("status", SerialStatusEnum.OUT_STOCK.getCode());
                param.put("refProductId", productSerialDTO.getRefProductId());
                //
                param.put(ParameterConstant.WAREHOUSE_ID, null);
            } else {
                param.put("status", SerialStatusEnum.IN_STOCK.getCode());
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE.getCode())) {
                param.put("status", SerialStatusEnum.IN_STOCK.getCode());
        } else {
            LinkProductSelectSerialEnum linkProductSelectSerialEnum = LinkProductSelectSerialEnum.getByBusinessType(businessType);
            param.put("businessType", linkProductSelectSerialEnum.getLinkBusinessType());
            param.put("status", linkProductSelectSerialEnum.getStatus());
            if (Objects.nonNull(productSerialDTO.getRefProductId()) && !Objects.equals(LinkProductSelectSerialEnum.UNKNOWN, linkProductSelectSerialEnum) && Objects.nonNull(linkProductSelectSerialEnum.getLinkBusinessType())) {
                param.put("refProductId", productSerialDTO.getRefProductId());
            }
        }
        if (Objects.nonNull(productSerialDTO.getSerial()) && !productSerialDTO.getSerial().isEmpty()) {
            param.put("seq", productSerialDTO.getSerial());
        }
        if (Objects.nonNull(productSerialDTO.getMemo()) && !productSerialDTO.getMemo().isEmpty()) {
            param.put("memo", productSerialDTO.getMemo());
        }
        PageHelper pageHelper = PageHelperUtil.getPageHelper(param, productSerialBalanceModel, productSerialDTO.getPageSize());
        List<ProductSerialBalanceEntity> entitys = (List<ProductSerialBalanceEntity>) PageHelperUtil.getEntityList(param, pageHelper, productSerialBalanceModel);
        // 相同表单类型的序列号不允许重复选择，比如新建两个调拨单选择同一个序列号
        entitys.removeIf(item -> Objects.equals(item.getBusinessType(), businessType));
        //排除采购退货时选择到的非采购入库的序列号
        if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE.getCode())) {
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("corpid", corpid);
            params.put("productId", productId);
            params.put("warehouseId", warehouseId);
            params.put("businessType", XbbRefTypeEnum.PURCHASE_INSTOCK.getCode());
            params.put("refProductId", productSerialDTO.getRefProductId());
            params.put("del", DelEnum.NORMAL.getDel());
            List<ProductSerialFlowEntity> productSerialFlowEntityList = productSerialFlowModel.findEntitys(params);
            List<String> serialList = new ArrayList<>();
            productSerialFlowEntityList.forEach(productSerialFlowEntity -> {
                serialList.add(productSerialFlowEntity.getSeq());
            });
            entitys.removeIf(item -> !serialList.contains(item.getSeq()));
        }
        JSONArray serialArray = new JSONArray();
        for (ProductSerialBalanceEntity entity : entitys) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(SerialEnum.SERIAL.getAttr(), entity.getSeq());
            jsonObject.put(SerialEnum.MEMO.getAttr(), entity.getMemo());
            serialArray.add(jsonObject);
        }
        productSerialVO.setSeq(serialArray);
        productSerialVO.setPageHelper(pageHelper);
        return productSerialVO;
    }

    @Override
    public PaasMenuEntity addMenu(AccordConfigMenuPojo accordConfigMenuPojo) throws XbbException {
        String corpid = accordConfigMenuPojo.getCorpid();
        PaasMenuEntity inventoryMenu = paasMenuModel.getByAlias(JXCMenuEnum.INVENTORY_MANAGEMENT.getAlias(), corpid);
        if (Objects.isNull(inventoryMenu)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nMessageUtil.getMessage(MessageConstant.MENU_NOT_EXIST));
        }
        long now = DateTimeUtil.getInt();
        Integer maxSort = paasMenuModel.maxSortInSubMenu(corpid, inventoryMenu.getId(), DelEnum.NORMAL.getDel());
        PaasMenuEntity seqMenuEntity = new PaasMenuEntity(inventoryMenu.getCorpid(), inventoryMenu.getAppId(), AccordConfigMenuEnum.SEQ_SEARCH.getName(), AccordConfigMenuEnum.SEQ_SEARCH.getAlias(), maxSort + 1, AccessLinkEnum.SEQ_SEARCH.getUrl(), AccessLinkEnum.SEQ_SEARCH.getMobileUrl(), 1, AccessLinkEnum.SEQ_SEARCH.getColor(), AccessLinkEnum.SEQ_SEARCH.getIcon(), accordConfigMenuPojo.getUserId());
        seqMenuEntity.setParentId(inventoryMenu.getId());
        //如果经销商标志为空，设置默认值
        if (Objects.isNull(seqMenuEntity.getDistributorMark())){
            seqMenuEntity.setDistributorMark(BasicConstant.ZERO);
        }
        paasMenuModel.insert(seqMenuEntity);
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ADD_MENU), accordConfigMenuPojo.getLoginUserName(), seqMenuEntity.getName());
        mongoLogHelp.buildLog(corpid, accordConfigMenuPojo.getUserId(), accordConfigMenuPojo.getLoginUserName(), OperateModuleTypeEnum.PAAS_MENU, OperateTypeEnum.NEW, "", "", memo, accordConfigMenuPojo.getHttpHeader());
        initJxcMenuHelp.generateFormWithMenu(accordConfigMenuPojo, corpid, now, seqMenuEntity, AccordConfigMenuEnum.SEQ_SEARCH);
        return seqMenuEntity;
    }

    @Override
    public void delProductSerial(String corpid, Long refProductId, Integer businessType) throws XbbException {
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID, corpid);
        params.put(StringConstant.BUSINESS_TYPE, businessType);
        params.put(BusinessConstant.REF_PRODUCT_ID, refProductId);
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<ProductSerialBalanceEntity> entitys = productSerialBalanceModel.findEntitys(params);
        updateLastSerialFlow(entitys, corpid);
    }
}
